package com.jx.jingxuan.widget.autoViewPager;

import android.content.Context;
import android.content.res.TypedArray;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.AttrRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;

import com.jx.jingxuan.R;
import com.jx.jingxuan.util.Tools;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * <li>Package: {@link WAutoViewPager}
 * <li>Author: cyh
 * <li>Date: 2017/6/22 9:54
 * <li>Discription: 轮播图控件
 */

public class WAutoViewPager extends FrameLayout implements ViewPager.OnPageChangeListener {
    private static final String TAG = "WAutoViewPager";
    private static final int AUTO_SCROLL = 100;//handler使用
    private static final int DEF_INTERVAL_TIME = 5000;//默认轮询间隔时间
    private static final int DEF_DURATION_TIME = 500;//默认滑动一张图片所需的时间

    private ViewPager viewPager;
    private IndicatorView indicatorView;//点控件

    private List<String> urls;//数据源


    private int currentPosition;//真正的位置

    private int intervalTime = DEF_INTERVAL_TIME;//轮询间隔时间
    private int durationTime = DEF_DURATION_TIME;//滑动一张图片所需的时间

    private OnPageChange onPageChange;//切换监听
    private int state = -1;

    private boolean isNeedScroll = true;

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
            startAutoScroll();
        }
    };
    private boolean isCanScroll = true;

    public WAutoViewPager(@NonNull Context context) {
        super(context);
        init(null);
    }

    public WAutoViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(attrs);
    }

    public WAutoViewPager(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(attrs);
    }

    /**
     * 初始化
     *
     * @param attrs
     */
    private void init(AttributeSet attrs) {
        float cRadius = Tools.dip2px(getContext().getApplicationContext(), IndicatorView.C_RADIUS);
        float cSpace = Tools.dip2px(getContext().getApplicationContext(), IndicatorView.C_SPACE);
        float rountRectWidth = cRadius * 2;
        int cNormalColor = IndicatorView.C_NORMAL_COLOR;
        int cSelectColor = IndicatorView.C_SELECT_COLOR;
        boolean needIndicator = false;
        if (attrs != null) {
            TypedArray array = getContext().obtainStyledAttributes(attrs, R.styleable.WAutoViewPager);
            cRadius = array.getDimension(R.styleable.WAutoViewPager_wav_cRadius, cRadius);
            cSpace = array.getDimension(R.styleable.WAutoViewPager_wav_cSpace, cSpace);
            rountRectWidth = array.getDimension(R.styleable.WAutoViewPager_wav_round_rect_width, rountRectWidth);
            cNormalColor = array.getColor(R.styleable.WAutoViewPager_wav_cNormalColor, IndicatorView.C_NORMAL_COLOR);
            cSelectColor = array.getColor(R.styleable.WAutoViewPager_wav_cSelectColor, IndicatorView.C_SELECT_COLOR);
            intervalTime = array.getInteger(R.styleable.WAutoViewPager_wav_interval_time, DEF_INTERVAL_TIME);
            durationTime = array.getInteger(R.styleable.WAutoViewPager_wav_duration_time, DEF_DURATION_TIME);
            needIndicator = array.getBoolean(R.styleable.WAutoViewPager_wav_need_indicator, true);
            isNeedScroll = array.getBoolean(R.styleable.WAutoViewPager_wav_need_autoscroll, true);
            array.recycle();
        }

        View view = LayoutInflater.from(getContext()).inflate(R.layout.layout_auto_viewpager, this);

        viewPager = (ViewPager) view.findViewById(R.id.auto_viewpager);
        controlViewPagerSpeed(durationTime);

        indicatorView = (IndicatorView) view.findViewById(R.id.auto_indicatorview);
        indicatorView.setcRadius(cRadius);
        indicatorView.setcSpace(cSpace);
        indicatorView.setRountRectWidth(rountRectWidth);
        indicatorView.setcNormalColor(cNormalColor);
        indicatorView.setcSelectColor(cSelectColor);

        if (!needIndicator) {
            indicatorView.setVisibility(GONE);
        }

        viewPager.setAdapter(adapter);
        viewPager.addOnPageChangeListener(this);
        viewPager.setCurrentItem(adapter.getStartPageIndex());
    }

    /**
     * 设置数据
     *
     * @param urls
     */
    public void setData(List<String> urls) {
        setData(urls, null);
    }

    MyAdapter adapter = new MyAdapter(getContext());

    /**
     * 设置数据，设置监听
     *
     * @param urls
     * @param onItemClickListener
     */
    public void setData(List<String> urls, MyAdapter.ItemCallback<? extends View> onItemClickListener) {
        setData(urls, onItemClickListener, null);
    }

    /**
     * @param urls
     * @param onItemClickListener
     * @param onPageChange        滑动监听
     */
    public void setData(List<String> urls, MyAdapter.ItemCallback<? extends View> onItemClickListener, OnPageChange onPageChange) {
        if (urls == null) {
            return;
        }
        //传入的图片列表与现在的相同，不用重新刷新列表
        if (this.urls != null && this.urls.equals(urls)) {
            return;
        }
        this.urls = urls;
        this.onPageChange = onPageChange;
        adapter.setOnItemClickListener(onItemClickListener);
        adapter.setData(urls);
        indicatorView.startDraw(urls.size());

        startAutoScroll();
    }

    /**
     * 可以在动态添加一些view
     *
     * @param views
     */
    public void addViewOnViewPager(int gravity, int marginTop, int marginLeft, int marginRight, int marginBottom, View... views) {
        if (views != null) {
            for (int i = 0; i < views.length; i++) {
                LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                params.gravity = gravity;
                params.topMargin = marginTop;
                params.leftMargin = marginLeft;
                params.rightMargin = marginRight;
                params.bottomMargin = marginBottom;
                views[i].setLayoutParams(params);
                addView(views[i]);
            }
        }
    }

    public void addViewOnViewPager(View... views) {
        addViewOnViewPager(Gravity.TOP, 0, 0, 0, 0, views);
    }

    /**
     * 替换viewpager自带的scroller，改变滑动速率
     *
     * @param durationTime
     */
    private void controlViewPagerSpeed(int durationTime) {
        try {
            Field mField;

            mField = ViewPager.class.getDeclaredField("mScroller");
            mField.setAccessible(true);

            FixedSpeedScroller mScroller = new FixedSpeedScroller(getContext(),
                    new DecelerateInterpolator());
            mScroller.setmDuration(durationTime);
            mField.set(viewPager, mScroller);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (isCanScroll) {
            //允许滑动则应该调用父类的方法
            return super.onTouchEvent(ev);
        } else {
            //禁止滑动则不做任何操作，直接返回true即可
            return true;
        }
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent arg0) {
        if (isCanScroll)
            return super.onInterceptTouchEvent(arg0);
        else
            return false;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            //用户自己操作时，取消自动滑动
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
                stopAutoScroll();
                break;
            //用户不操作时，恢复自动滑动
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                startAutoScroll();
                break;
        }
        if (isCanScroll)
            return super.dispatchTouchEvent(ev);
        else
            return false;
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        stopAutoScroll();
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (adapter != null && adapter.hasData()) {
            startAutoScroll();
            viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
        }
    }

    /**
     * 开始自动滚动
     */
    private void startAutoScroll() {
        if (handler != null && !handler.hasMessages(AUTO_SCROLL) && isNeedScroll) {
            handler.sendEmptyMessageDelayed(AUTO_SCROLL, intervalTime);
        }
    }

    /**
     * 停止自动滚动
     */
    private void stopAutoScroll() {
        if (handler != null && handler.hasMessages(AUTO_SCROLL)) {
            handler.removeMessages(AUTO_SCROLL);
        }
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//        if (positionOffset == 0) {//滑动停止时
//            if (position == 0) {//滑到第一张图片，则跳转到倒数第二张
//                currentPosition = urls.size() - 2;
//                indicatorView.moveSelectRountRect(currentPosition - 1, positionOffset);
//            } else if (position == urls.size() - 1) {//滑到最后一张图片则，则跳转到第二张
//                currentPosition = 1;
//                indicatorView.moveSelectRountRect(currentPosition - 1, positionOffset);
//            } else {//普通状态
//                currentPosition = position;
//                indicatorView.moveSelectRountRect(currentPosition - 1, positionOffset);
//            }
//        } else {//滑动时
//            indicatorView.moveSelectRountRect(position - 1, positionOffset);
//        }
        if (urls == null) {
            return;
        }
        Log.d(TAG, "onPageScrolled: " + position);
        currentPosition = position % urls.size();
        //判断当前位置,只调用一次
        if (currentPosition != state) {
            state = currentPosition;
            if (onPageChange != null) {
                onPageChange.onPageSelected(currentPosition);
            }
        }
        indicatorView.moveSelectRountRect(currentPosition, positionOffset);
    }

    @Override
    public void onPageSelected(int position) {
        //拿到的当前位置不正确
        //Log.d(TAG, "onPageSelected: "+currentPosition);
    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }

    public interface OnPageChange {
        void onPageSelected(int position);
    }

    public static class MyAdapter<T extends View> extends PagerAdapter {
        private List<String> urls;//数据源
        private Context mContext;

        private ItemCallback<T> itemCallback;

        private boolean needNotify;

        public MyAdapter(Context context) {
            urls = new ArrayList<>();
            mContext = context;
            needNotify = false;
        }

        /**
         * url列表赋值
         *
         * @param urls
         */
        public void setData(List<String> urls) {
            if (this.urls == null) {
                this.urls = new ArrayList<>();
            }
            this.urls.clear();
            this.urls.addAll(urls);
            needNotify = true;
            notifyDataSetChanged();
        }

        @Override
        public View instantiateItem(ViewGroup container, int position) {
            if (itemCallback == null) {
                return container;
            }
            final T imgView = itemCallback.getItemView();

            if (imgView != null) {
                container.addView(imgView);
            } else {
                return container;
            }

            //加载图片
            final int currentPosition = getBannerIndexOfPosition(position);
            final String url = urls.get(currentPosition);

            itemCallback.loadItemData(imgView, url, currentPosition);

            imgView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (itemCallback != null) {
                        itemCallback.onItemClick(imgView, url, currentPosition);
                    }
                }
            });
            return imgView;
        }

        @Override
        public int getItemPosition(Object object) {
//            if (needNotify) {
//                needNotify = false;
//                return POSITION_NONE;
//            }
//            return super.getItemPosition(object);
            return POSITION_NONE;
        }

        @Override
        public int getCount() {
            return Integer.MAX_VALUE;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        /**
         * 计算图片的位置
         *
         * @param position
         * @return
         */
        private int getBannerIndexOfPosition(int position) {
            return position % urls.size();
        }

        public boolean hasData() {
            if (urls != null && urls.size() > 0) {
                return true;
            } else {
                return false;
            }
        }

        /**
         * 计算一开始跳转到哪张图片
         *
         * @return
         */
        public int getStartPageIndex() {
            int index = getCount() / 2;
            if (urls == null || urls.size() == 0) {
                return index;
            }
            int remainder = index % urls.size();
            index = index - remainder;
            return index;
        }

        public void setOnItemClickListener(ItemCallback itemCallback) {
            this.itemCallback = itemCallback;
        }

        public interface ItemCallback<T extends View> {
            T getItemView();//item的view

            void loadItemData(T view, String url, int position);

            void onItemClick(T view, String url, int position);
        }
    }

    public void setNeedScroll(boolean isNeedScroll) {
        this.isNeedScroll = isNeedScroll;
    }

    public void setNeedSlidingScroll(boolean isNeedSlidingScroll){
        this.isCanScroll = isNeedScroll;
    }
}